﻿using CamstarAPI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using uMES.LeanManufacturing.DBUtility;
using uMES.LeanManufacturing.ParameterDTO;

namespace uMES.LeanManufacturing.ReportBusiness
{
  public  class uMESWorkflowEditorBusiness
    {
        /// <summary>
        /// 获取工序信息
        /// </summary>
        /// <param name="workflowId"></param>
        /// <returns></returns>
        public DataTable GetWorkflowStepInfoByWorkflowId(string workflowId) {
            string strSql = @"select ws.workflowstepname,ws.workflowstepid,s.specno,s.specid,o.operationname,o.operationid,t.teamid,t.teamname,fa.factoryname,fa.factoryid,s.unitworktime,
s.setupworktime,s.issynergic,decode(s.issynergic,null,'否',0,'否',1,'是') SynergicName,s.specrevision,
listagg( a.operationname,',' ) within group (order by a.operationid) detailopname,
listagg( a.setupworktime,',' ) within group (order by a.operationid) detailsetupworktime,
listagg( a.unitworktime,',' ) within group (order by a.operationid)  detailunitworktime,s.IsModifyWorkHours
from workflow w
left join workflowstep ws on ws.workflowid=w.workflowid
left join specbase sb on sb.specbaseid=ws.specbaseid
left join spec s  on s.specid=nvl(sb.revofrcdid,ws.specid)
left join team t on t.teamid=s.teamid
left join operation o on o.operationid=s.operationid
left join factory fa on fa.factoryid=s.factoryid
left join (
select op.operationid,op.operationname,wh.unitworktime,wh.setupworktime,wh.specid from workhoursdetail wh
left join operation op on op.operationid=wh.operationid
) a on a.specid=s.specid";
            strSql +=$" where w.workflowid='{workflowId}' ";

            strSql += @"group by ws.workflowstepname,ws.workflowstepid,s.specno,s.specid,o.operationname,o.operationid,t.teamid,t.teamname,fa.factoryname,fa.factoryid,s.unitworktime,
s.setupworktime,s.issynergic,s.specrevision,s.IsModifyWorkHours";
            strSql += " order by ws.workflowstepid ";
            return OracleHelper.Query(strSql).Tables[0];
        }
        /// <summary>
        /// 查询工种信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public DataTable GetOperationInfoById(string id) {
            string strSql = @"select fa.factoryname,fa.factoryid,t.teamid,t.teamname,o.operationname,o.operationid,o.synergiccompanyid  from operation o 
left join team t on t.teamid=o.teamid
left join factory fa on fa.factoryid=t.factoryid";
            strSql += $" where o.operationid='{id}' ";

            return OracleHelper.Query(strSql).Tables[0];
        }

        /// <summary>
        /// 校验工艺是否能够修改
        /// </summary>
        /// <param name="worklfowName"></param>
        /// <param name="workflowRev"></param>
        /// <returns></returns>
       public DataTable ValidateWorkflow(string worklfowName, string workflowRev)
        {
            string strSql = @"select w.workflowid,count(di.id) isdispatch,count(a.containername) containerNum  from workflow w 
left join workflowbase wb on wb.workflowbaseid=w.workflowbaseid
left join dispatchinfo di on di.workflowid=w.workflowid 
left join (
select c.containername,ws.workflowid from workflowstep ws
left join currentstatus cu on cu.workflowstepid=ws.workflowstepid
left join container c on c.currentstatusid=cu.currentstatusid and c.status!=0
where  c.containername is not null
) a on a.workflowid=w.workflowid ";

            strSql += $" where wb.workflowname='{worklfowName}' and w.workflowrevision='{workflowRev}' ";

            strSql += " group by w.workflowid ";

            return OracleHelper.Query(strSql).Tables[0];
        }

        /// <summary>
        /// 创建工艺
        /// </summary>
        /// <returns></returns>
        public ResultModel CreateNewWorkflow(string apiUsername,string apiUserPassword,DataTable dsworkflow, DataTable dtspec, string strOldVersion,bool isValidateWorkHours,string createEmployee="") {
            ResultModel re = new ResultModel(false,"");
            //创建工序
            foreach (DataRow dtSpecRow in dtspec.Rows) {
                re = SaveSpec(apiUsername, apiUserPassword, dtSpecRow,isValidateWorkHours);
                if (re.IsSuccess == false)
                    return re;
            }
            //创建工艺
            var workflowRow = dsworkflow.Rows[0];
            List<ClientAPIEntity> p_dataEntityList =new List<ClientAPIEntity>();
            ClientAPIEntity entity = new ClientAPIEntity();

            entity = new ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, workflowRow["WorkflowName"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("Revision", InputTypeEnum.Details, DataTypeEnum.DataField, workflowRow["workFlowRevision"].ToString(), "");
            p_dataEntityList.Add(entity);

            if (!string.IsNullOrWhiteSpace(workflowRow["Factory"].ToString()))
            {
                entity = new ClientAPIEntity("Factory", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, workflowRow["Factory"].ToString(), "");
                p_dataEntityList.Add(entity);
            }


            entity = new ClientAPIEntity("Description", InputTypeEnum.Details, DataTypeEnum.DataField, workflowRow["Description"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("Status", InputTypeEnum.Details, DataTypeEnum.DataField, workflowRow["Status"].ToString(), "");
            p_dataEntityList.Add(entity);

            if (!string.IsNullOrWhiteSpace(createEmployee)) {
                entity = new ClientAPIEntity("CreateEmployee", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, createEmployee, "");
                p_dataEntityList.Add(entity);
            }


            var strmsg = "";
            var api = new CamstarClientAPI(apiUsername, apiUserPassword);
            string workflowName = workflowRow["WorkflowName"].ToString();
            string workflowRev = workflowRow["workFlowRevision"].ToString();
            re.IsSuccess = api.CreateWorkflowRevsion("Workflow",ref workflowName, ref strOldVersion,ref workflowRev,p_dataEntityList, dtspec,ref strmsg);
            re.Message = strmsg;
            return re;
        }
        /// <summary>
        /// 创建工序
        /// </summary>
        /// <returns></returns>
        public ResultModel SaveSpec(string apiUserNmae, string apiPassword, DataRow dtSpecRow,bool isValidateWorkHours=true) {
            ResultModel re = new ResultModel(false, "");

            //可能或出现的subentity
            Dictionary<string, Dictionary<string, List<ClientAPIEntity>>> p_SubentityInfo = new Dictionary<string, Dictionary<string, List<ClientAPIEntity>>>();
          var temp=  GnerateSpecSubEntitys(dtSpecRow,out p_SubentityInfo);
            if (isValidateWorkHours&&temp.Item1 == false) {
                re.Message = temp.Item2;
                return re;
            }
            
            var entity = new ClientAPIEntity();
            var p_dataEntityList = new List<ClientAPIEntity>();
            //主要信息赋值
            entity = new ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, dtSpecRow["WorkflowStepName"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("Revision", InputTypeEnum.Details, DataTypeEnum.DataField, dtSpecRow["SpecRev"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("Operation", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, dtSpecRow["OperationName"].ToString(), "");
            p_dataEntityList.Add(entity);

         

            entity = new ClientAPIEntity("SpecNO", InputTypeEnum.Details, DataTypeEnum.DataField, dtSpecRow["SpecNO"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("UnitWorkTime", InputTypeEnum.Details, DataTypeEnum.DataField, dtSpecRow["UnitWorkTime"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("SetupWorkTime", InputTypeEnum.Details, DataTypeEnum.DataField, dtSpecRow["SetupWorkTime"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("Team", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, dtSpecRow["TeamName"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("Factory", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, dtSpecRow["FactoryName"].ToString(), "");
            p_dataEntityList.Add(entity);

            entity = new ClientAPIEntity("IsSynergic", InputTypeEnum.Details, DataTypeEnum.DataField, dtSpecRow["IsSynergic"].ToString(), "");
            p_dataEntityList.Add(entity);

            if (dtSpecRow.Table.Columns.Contains("IsModifyWorkHours"))
            {
                entity = new ClientAPIEntity("IsModifyWorkHours", InputTypeEnum.Details, DataTypeEnum.DataField, dtSpecRow["IsModifyWorkHours"].ToString(), "");
                p_dataEntityList.Add(entity);
            }

            var api = new CamstarClientAPI(apiUserNmae, apiPassword);
            var strMsg = "";

            //若存在，执行修改
            string strSql =string.Format(@"select s.specid,sb.revofrcdid,s.specrevision from spec s
left join specbase sb on sb.specbaseid=s.specbaseid
where sb.specname='{0}'", dtSpecRow["WorkflowStepName"].ToString());
            DataTable tempSpec = OracleHelper.Query(strSql).Tables[0];
            DataRow[] tempDrs = tempSpec.Select("specrevision='" + dtSpecRow["SpecRev"].ToString() + "'");
            if (tempDrs.Length>0)
            {
                if (tempSpec.Rows.Count == 1)//就只有这一个临时版本
                {
                    entity = new ClientAPIEntity("IsRevOfRcd", InputTypeEnum.Details, DataTypeEnum.DataField, "1", "");
                    p_dataEntityList.Add(entity);
                    //p_dataEntityList.Find(en=>en.ClientDataName.Equals("IsRevOfRcd")).ClientDataValue="1";
                }
                int oldCount = 0;
                strSql = $"select * from workhoursdetail wh where wh.specid='{tempDrs[0]["specid"].ToString()}'";
                oldCount = OracleHelper.Query(strSql).Tables[0].Rows.Count;

                re.IsSuccess = api.UpdateModelHasSubentityList("SpecMaintDoc", "SpecMaint", dtSpecRow["WorkflowStepName"].ToString(), dtSpecRow["SpecRev"].ToString(), 
                    "RO",p_dataEntityList, "WorkHoursDetail", p_SubentityInfo["WorkHoursDetail"], oldCount, ref strMsg);
            }
            else {
                entity = new ClientAPIEntity("IsRevOfRcd", InputTypeEnum.Details, DataTypeEnum.DataField, "0", "");
                p_dataEntityList.Add(entity);

                DataRow[] revofrcdRev = tempSpec.Select("specid=revofrcdid");
                if (revofrcdRev.Length == 0)
                {
                    re.IsSuccess = api.CreateModel("SpecMaint", p_dataEntityList, p_SubentityInfo,ref strMsg);
                }
                else
                {
                    re.IsSuccess = api.CreateNewModelRevision("SpecMaint", dtSpecRow["WorkflowStepName"].ToString(), revofrcdRev[0]["specrevision"].ToString(), p_dataEntityList, p_SubentityInfo, ref strMsg);
                }
            }

            re.Message = strMsg;
            return re;
        }

        /// <summary>
        /// 工序的subentity 
        /// </summary>
        /// <param name="rwSpec"></param>
        /// <param name="p_SubentityInfo"></param>
        /// <returns></returns>
        Tuple<bool, string> GnerateSpecSubEntitys(DataRow rwSpec, out Dictionary<string, Dictionary<string, List<ClientAPIEntity>>> p_SubentityInfo)
        {
            string strSpecName = rwSpec["OperationName"].ToString();           
            //处理一工序，多工种情况
            p_SubentityInfo = new Dictionary<string, Dictionary<string, List<ClientAPIEntity>>>();//可能有的subentity
            p_SubentityInfo.Add("WorkHoursDetail", new Dictionary<string, List<ClientAPIEntity>>());
            if (!strSpecName.Contains('、'))
            {
                return new Tuple<bool, string>(true, ""); ;
            }
            if (rwSpec["detailsetupworktime"].ToString().Contains(",") || rwSpec["detailunitworktime"].ToString().Contains(","))
            {
                //分割工序，确定每个工时关联的operation
                string[] operations = strSpecName.Split('、');
                string[] unitTimes = rwSpec["detailunitworktime"].ToString().Split(',');
                string[] setupTimes = rwSpec["detailsetupworktime"].ToString().Split(',');
                int sumUnitWorkTime = 0, sumSetupWorkTime = 0;
                if (operations.Length != unitTimes.Length || operations.Length != setupTimes.Length || operations.Length != 2)
                {
                    return new Tuple<bool, string>(false, "工序里包含的工种和工时的种类不一致");
                }

                Dictionary<string, List<ClientAPIEntity>> sub = new Dictionary<string, List<ClientAPIEntity>>();// { "WorkHoursDetail" };
                List<ClientAPIEntity> rowEntity = new List<ClientAPIEntity>();
                ClientAPIEntity entity = new ClientAPIEntity();

                for (int i = 0; i < operations.Length; i++)
                {
                    int temp;
                    if (!int.TryParse(setupTimes[i], out temp))
                    {
                        return new Tuple<bool, string>(false, "工时数据格式不对");
                    }
                    sumSetupWorkTime += temp;
                    if (!int.TryParse(unitTimes[i], out temp))
                    {
                        return new Tuple<bool, string>(false, "工时数据格式不对");
                    }
                    sumUnitWorkTime += temp;
                    rowEntity = new List<ClientAPIEntity>();

                    entity= new ClientAPIEntity("Operation", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, operations[i].ToString(), "");
                    rowEntity.Add(entity);

                    entity = new ClientAPIEntity("SetupWorkTime", InputTypeEnum.Details, DataTypeEnum.DataField, setupTimes[i].ToString(), "");
                    rowEntity.Add(entity);

                    entity = new ClientAPIEntity("UnitWorkTime", InputTypeEnum.Details, DataTypeEnum.DataField, unitTimes[i].ToString(), "");
                    rowEntity.Add(entity);


                    sub.Add(i.ToString(), rowEntity);
                }
                //重新赋值工序上的总工时
                rwSpec["UnitWorkTime"] = sumUnitWorkTime; rwSpec["SetupWorkTime"] = sumSetupWorkTime;
                
                p_SubentityInfo["WorkHoursDetail"]=sub;
            }
            else
            {
                int temp;
                if (!int.TryParse(rwSpec["UnitWorkTime"].ToString(), out temp))
                {
                    return new Tuple<bool, string>(false, "工时数据格式不对");
                }
                if (!int.TryParse(rwSpec["SetupWorkTime"].ToString(), out temp))
                {
                    return new Tuple<bool, string>(false, "工时数据格式不对");
                }
            }
            //
            return new Tuple<bool, string>(true, "");
        }

        /// <summary>
        /// 删除工艺
        /// </summary>
        /// <param name="apiUserName"></param>
        /// <param name="apiPassword"></param>
        /// <param name="workflowName"></param>
        /// <param name="workflowRev"></param>
        /// <returns></returns>
        public ResultModel DeleteWorkflow(string apiUserName,string apiPassword,string workflowName,string workflowRev) {
            ResultModel re = new ResultModel(false,"");
            var api = new CamstarClientAPI(apiUserName, apiPassword);

            var strMsg = "";
           re.IsSuccess= api.DeleteModel("WorkflowMaint", workflowName, workflowRev,"RO",ref strMsg);

            return re;

        }

        /// <summary>
        /// 获取能工时更改的临时工艺信息
        /// </summary>
        /// <param name="para"></param>
        /// <returns></returns>
        public uMESPagingDataDTO GetCanWorkHoursWorkflowInfo(Dictionary<string,string> para) {
            uMESPagingDataDTO re = new uMESPagingDataDTO();

            string strSql = @"select pb.productname,p.description productdesc,wb.workflowname,
w2.workflowrevision workflowrev,w2.workflowid from product p
left join productbase pb on pb.productbaseid=p.productbaseid
left join workflow w on w.workflowid=p.workflowid
left join workflowbase wb on wb.workflowbaseid=w.workflowbaseid 
left join workflow w2 on w2.workflowbaseid=wb.workflowbaseid
where 1=1 ";

            if (para.ContainsKey("ProductName") && !string.IsNullOrWhiteSpace(para["ProductName"])) {
                strSql += string.Format(" and pb.productname like '%{0}%' ",para["ProductName"]);
            }
            if (para.ContainsKey("WorkflowName") && !string.IsNullOrWhiteSpace(para["WorkflowName"]))
            {
                strSql += string.Format(" and wb.workflowname like '%{0}%' ",para["WorkflowName"]);
            }
            strSql += " and w2.workflowrevision like 'LS%' ";
            strSql += @" group by pb.productname,p.description,wb.workflowname,
w2.workflowrevision,w2.workflowid";
            strSql += " order by w2.workflowid desc ";

            DataTable dt = OracleHelper.Query(strSql).Tables[0];
            DataTable reDt = dt.Clone();
            //筛选掉已经使用的
            foreach (DataRow dr in dt.Rows) {
               var temp= ValidateWorkflow(dr["workflowname"].ToString(),dr["workflowrev"].ToString());
                if (temp.Rows[0]["isdispatch"].ToString() != "0" || temp.Rows[0]["containerNum"].ToString() != "0")
                {
                    continue;
                }
                reDt.ImportRow(dr);
            }

            re.DBTable = reDt;
            return re;
        }

        /// <summary>
        /// 继承工艺附件信息
        /// </summary>
        /// <param name="workflowName"></param>
        /// <param name="oldRev"></param>
        /// <param name="newRev"></param>
        public void InheritAttachmentInfo(string workflowName,string oldRev,string newRev) {
            string strSql = @"	select w.workflowid orgworkflowid,w.workflowrevision,ck.* from workflow w
						left join workflowbase wb on wb.workflowbaseid=w.workflowbaseid
						left join ckattachment ck on ck.workflowid=w.workflowid";
            strSql += $" where wb.workflowname='{workflowName}' and w.workflowrevision in ('{newRev}','{oldRev}') ";

            DataTable dt = OracleHelper.Query(strSql).Tables[0];

            DataRow[] olddr = dt.Select($"workflowrevision='{oldRev}'");
            DataRow[] newdr = dt.Select($"workflowrevision='{newRev}'");

            if (olddr[0].IsNull("workflowid")) {
                return;
            }

            string insertSql = string.Format(@"INSERT INTO ckattachment(ckattachmentid,ckattachmentname,ckattachtype,cksubmitdate,ckurl,workflowid)
values ('{0}','{1}','{2}',sysdate,'{3}','{4}') ", Guid.NewGuid().ToString(),olddr[0]["ckattachmentname"].ToString(),olddr[0]["ckattachtype"].ToString(), 
olddr[0]["ckurl"].ToString(), newdr[0]["orgworkflowid"].ToString());

            OracleHelper.ExecuteSql(insertSql);


        }
        /// <summary>
        /// 保存附件
        /// </summary>
        /// <param name="para"></param>
        public void SaveObjectDoc(Dictionary<string,string> para) {

            ArrayList strSqls = new ArrayList();

            string sql = string.Format(@"delete ckattachment where workflowid='{0}' and ckattachmentname='{1}'", para["workflowid"], para["ckattachmentname"]);
            strSqls.Add(sql);

             sql = string.Format(@"INSERT INTO ckattachment(ckattachmentid,ckattachmentname,ckattachtype,cksubmitdate,ckurl,workflowid)
values ('{0}','{1}','{2}',sysdate,'{3}','{4}') ", Guid.NewGuid().ToString(), para["ckattachmentname"].ToString(), para["ckattachtype"].ToString(),
para["ckurl"].ToString(), para["workflowid"].ToString());
            strSqls.Add(sql);


             OracleHelper.ExecuteSqlTran(strSqls);
        }
    }
}
